package com.feicheng.lanniao.controller.weChatNativePayV2;
import com.alibaba.fastjson.JSONObject;
import com.feicheng.lanniao.controller.weChatNativePay.constant.WechatPayConfig;
import com.feicheng.lanniao.service.IPayOrderv2Service;
import com.feicheng.lanniao.service.QuotaRecordService;
import com.feicheng.lanniao.util.AesUtil;
import com.feicheng.lanniao.util.WechatPayUtils;

import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author tianchunlei
 * @Des //微信扫码支付后异步回调接口
 * @Date 2021/10/17
 **/
@RestController
@Slf4j
public class WechatNativeV2Callback {
	@Autowired
	QuotaRecordService quotaRecordService;
    @Autowired
    private IPayOrderv2Service iPayOrderv2Service;
    @PostMapping("/result/callback")
    public Map<String,String> notifyWeixinPay(@RequestBody Map body, HttpServletRequest request){
        log.info("=============>WechatNativeV2Callback接口方法进入<=============");
        log.info("=============>body为: "+body+" <=============");
        /*
            响应给微信的数据
         */
        Map<String,String> response = new HashMap<>();
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        ObjectMapper objectMapper = new ObjectMapper();
        /*
        解析报文
         */
        try {
            String data = objectMapper.writeValueAsString(body);
            String message = timestamp + "\n" + nonce + "\n" + data + "\n";
            /*
            获取应答签名
             */
            String sign = request.getHeader("Wechatpay-Signature");
            /*
            获取平台对应证书
             */
            String serialNo = request.getHeader("Wechatpay-Serial");
            if (!WechatPayConfig.CERTIFICATE_MAP.containsKey(serialNo)) {
                WechatPayConfig.CERTIFICATE_MAP = WechatPayUtils.refreshCertificate();
            }

            X509Certificate x509Certificate = WechatPayConfig.CERTIFICATE_MAP.get(serialNo);
            if (!WechatPayUtils.verify(x509Certificate, message.getBytes(), sign)) {
                throw new IllegalArgumentException("微信支付签名验证失败:" + message);
            }
            log.info("=============>签名验证成功<=============");
            Map<String, String> resource = (Map) body.get("resource");
            /*
                回调报文解密
             */
            AesUtil aesUtil = new AesUtil(WechatPayConfig.KEY.getBytes());
            /*
                解密后json字符串
             */
            String decryptToString = aesUtil.decryptToString(
                    resource.get("associated_data").getBytes(),
                    resource.get("nonce").getBytes(),
                    resource.get("ciphertext"));
            log.info("=============>decryptToString: {}<=============", decryptToString);
            /*
                获取微信支付返回的信息
             */
            Map<String, Object> resultData = objectMapper.readValue(decryptToString, Map.class);
            log.info("=============>resultData: {}<=============" + resultData);
            /*
                获取交易状态然后处理后续业务逻辑
                交易状态，枚举值：
                SUCCESS：支付成功
                REFUND：转入退款
                NOTPAY：未支付
                CLOSED：已关闭
                REVOKED：已撤销（付款码支付）
                USERPAYING：用户支付中（付款码支付）
                PAYERROR：支付失败(其他原因，如银行返回失败)
             */
            if ("SUCCESS".equals(resultData.get("trade_state"))) {
                /*
                 1.获取支付的交易单号 transaction_id
                 */
                String transaction_id = resultData.get("transaction_id").toString();
                log.info("=============>transaction_id(获取支付的交易单号)={}<=============",transaction_id);
                /*
                 2.商户订单号 out_trade_no
                 */
                String out_trade_no = resultData.get("out_trade_no").toString();
                log.info("=============>out_trade_no(商户订单号)={}<=============",out_trade_no);
                /*
                 3.附属参数 attach
                 */

                String attach = (String) resultData.get("attach");
                JSONObject attchJsonObject = JSONObject.parseObject(attach);
                log.info("=============>attchJsonObject(attchJsonObject)={}<=============",attchJsonObject);
                Integer clientId = attchJsonObject.getInteger("clientId");
                Integer orderTypeId = attchJsonObject.getInteger("orderTypeId");
                if(orderTypeId >= 9 && orderTypeId <= 16) {
                	quotaRecordService.updateQuota(clientId, orderTypeId);
                }
                String description = attchJsonObject.getString("description");
                log.info("=============>client={},orderTypeId={},description={}<=============",clientId,orderTypeId,description);
                /*
                 4.付款银行 bank_type
                 */
                String bankType =  (String) resultData.get("bank_type");
                log.info("=============>bank_type(付款银行)={}<=============",bankType);
                /*
                 5.支付完成时间 success_time
                 */
                String successTime = (String) resultData.get("success_time");
                log.info("=============>success_time(支付完成时间)={}<=============",successTime);
                /*
                 6.支付者 payer
                  6.1用户标识 openid
                 */
                Map payer = (HashMap)resultData.get("payer");
                String openid = (String)payer.get("openid");
                log.info("=============>openid(用户标识)={}<=============",openid);
                /*
                 7.交易状态描述 trade_state_desc
                 */
                String tradeStateDesc = (String)resultData.get("trade_state_desc");
                log.info("=============>tradeStateDesc(交易状态描述)={}<=============",tradeStateDesc);
                /*
                 8.订单金额 amount
                    8.1总金额 total
                    8.2货币类型 currency
                 */
                Map amount = (HashMap) resultData.get("amount");
                Integer total = (Integer) amount.get("total");
                log.info("=============>total(总金额)={}<=============",total);
                String currency = (String)amount.get("currency");
                log.info("=============>currency(货币类型)={}<=============",currency);
                /*
                此位置有业务处理的
                 */
                iPayOrderv2Service.updateOrderInfo(description,out_trade_no,successTime);

                response.put("code", "SUCCESS");
                response.put("message", "成功");
            }
        }catch (Exception e){
            response.put("code", "fail");
            response.put("message", "系统错误");
            e.printStackTrace();
        }
        return response;
    }

}
